//
// Created by 17775 on 2024/10/16.
//

#include "LiveMode_Background.h"
#include  <QDebug>
#include <QElapsedTimer>
#include <QtConcurrent/qtconcurrentrun.h>

LiveMode_Background::LiveMode_Background(int &docId): _nDocIdLive(docId) {

}

void LiveMode_Background::setFrameSpan(int nFrames) {
    RayCi_LiveMode_Background_Recording_Settings_setFrameSpan(_nDocIdLive, nFrames);
}

bool LiveMode_Background::isFrameSpan() const {
    bool bFrameSpan = false;
    RayCi_LiveMode_Background_Recording_Settings_isFrameSpan(_nDocIdLive, &bFrameSpan);
    return bFrameSpan;
}

bool LiveMode_Background::isFrameSpanAvailable() const {
    bool bFrameSpanAvailable = false;
    RayCi_LiveMode_Background_Recording_Settings_isFrameSpanAvailable(_nDocIdLive, &bFrameSpanAvailable);
    return bFrameSpanAvailable;
}

void LiveMode_Background::setTimeSpan(double dTime) {
    RayCi_LiveMode_Background_Recording_Settings_setTimeSpan(_nDocIdLive, dTime);
}

bool LiveMode_Background::isTimeSpan() {
    bool bTimeSpan = false;
    RayCi_LiveMode_Background_Recording_Settings_isTimeSpan(_nDocIdLive, &bTimeSpan);
    return bTimeSpan;
}

bool LiveMode_Background::isTimeSpanAvailable() {
    bool bTimeSpanAvailable = false;
    RayCi_LiveMode_Background_Recording_Settings_isTimeSpanAvailable(_nDocIdLive, &bTimeSpanAvailable);
    return bTimeSpanAvailable;
}

void LiveMode_Background::setCurrentExposure() {
    RayCi_LiveMode_Background_Recording_Settings_setCurrentExposure(_nDocIdLive);
}

bool LiveMode_Background::isCurrentExposure() {
    bool bCurrentExposure = false;
    RayCi_LiveMode_Background_Recording_Settings_isCurrentExposure(_nDocIdLive, &bCurrentExposure);
    return bCurrentExposure;
}

bool LiveMode_Background::isCurrentExposureAvailable() {
    bool bCurrentExposureAvailable = false;
    RayCi_LiveMode_Background_Recording_Settings_isCurrentExposureAvailable(_nDocIdLive, &bCurrentExposureAvailable);
    return bCurrentExposureAvailable;
}

void LiveMode_Background::setAllExposure() {
    RayCi_LiveMode_Background_Recording_Settings_setAllExposure(_nDocIdLive);
}

bool LiveMode_Background::isAllExposure() {
    bool bAllExposure = false;
    RayCi_LiveMode_Background_Recording_Settings_isAllExposure(_nDocIdLive, &bAllExposure);
    return bAllExposure;
}

bool LiveMode_Background::isAllExposureAvailable() {
    bool bAllExposureAvailable = false;
    RayCi_LiveMode_Background_Recording_Settings_isAllExposureAvailable(_nDocIdLive, &bAllExposureAvailable);
    return bAllExposureAvailable;
}



void LiveMode_Background::loadCorrectionBackground()  {
    bool dataAvailable = false;
    QElapsedTimer timer;
    timer.start();

    RayCi_LiveMode_Background_isLoadableDataAvailable(_nDocIdLive, &dataAvailable);
    if (dataAvailable) {
        bool canLoad = false;
        int LastFrame=0;
        RayCi_LiveMode_Background_Recording_Settings_getFrameStepCount(_nDocIdLive, &LastFrame);
        RayCi_LiveMode_Background_canLoad(_nDocIdLive, &canLoad);
        if (canLoad) {
            RayCi_LiveMode_Background_load(_nDocIdLive);
            bool bRecording=true;
            double totaltime=5800;

            while (bRecording) {
                int nStatus=-1;
                RayCi_LiveMode_Background_getState(_nDocIdLive, &nStatus);
                // qDebug()<<"nStatus"<<nStatus;
                double durationtime = timer.elapsed();
                int  proportion = durationtime/totaltime*100;
                int frame=durationtime/100;

                // qDebug()<<"index"<<0<<"proportion"<<proportion<<"frame"<<frame<<"durationtime"<<durationtime;
                emit BackGroundProgress(0,proportion,frame,durationtime);
                if (nStatus!= 5) {
                    bRecording = false;
                }

                QThread::msleep(50);
            }
                emit  BackGroundProgress(0,100,LastFrame,timer.elapsed());
        }
        if (!canLoad)
            emit  BackGroundProgress(0,100,LastFrame,timer.elapsed());
    }
    emit stopbackgroundWorkerThread();
}

void  LiveMode_Background::saveCorrectionBackground() const {
    bool canSave = false;
    QElapsedTimer timer;
    timer.start();
    int LastFrame=0;
    RayCi_LiveMode_Background_Recording_Settings_getFrameStepCount(_nDocIdLive, &LastFrame);
    RayCi_LiveMode_Background_canSave(_nDocIdLive, &canSave);
    if (canSave) {
        RayCi_LiveMode_Background_save(_nDocIdLive);
        bool bRecording=true;
        double totaltime=4700;

            while (bRecording) {
                int nStatus=-1;
                RayCi_LiveMode_Background_getState(_nDocIdLive, &nStatus);
                // qDebug()<<"nStatus"<<nStatus;
                double durationtime = timer.elapsed();
                int  proportion = durationtime/totaltime*100;
                int frame=durationtime/100;

                // qDebug()<<"index"<<1<<"proportion"<<proportion<<"frame"<<frame<<"durationtime"<<durationtime;
                emit BackGroundProgress(0,proportion,frame,durationtime);
                if (nStatus!= 3)
                    bRecording = false;
                QThread::msleep(50);
                 }
                     emit  BackGroundProgress(1,100,LastFrame,timer.elapsed());
    }
    if (!canSave)
    emit  BackGroundProgress(1,100,LastFrame,timer.elapsed());

    emit stopbackgroundWorkerThread();
}


void  LiveMode_Background::clearCorrectionBackground() const {
    bool canClear = false;
    RayCi_LiveMode_Background_canClear(_nDocIdLive, &canClear);
    if (canClear) {
        RayCi_LiveMode_Background_clear(_nDocIdLive);
    }
    emit  BackGroundProgress(2,100,0,0);
}

QString LiveMode_Background::startBackgroundMeasurement() {
    bool bAvailable = false;
    RayCi_LiveMode_Background_Recording_isAvailable(_nDocIdLive, &bAvailable);
    bool isAllExposure = true;
    RayCi_LiveMode_Background_Recording_Settings_isAllExposure(_nDocIdLive, &isAllExposure);
    char szRemark_buffer[100];
    int nSize = _countof(szRemark_buffer);
    int nowFreme=0;
    RayCi_LiveMode_Background_Recording_Settings_getFrameSpan(_nDocIdLive, &nowFreme);
    if(bAvailable) {
        emit enableUI(false);
        RayCi_LiveMode_Background_Recording_start(_nDocIdLive);
        bool bRecording = true;

        double baseFrameTime=400*(nowFreme/8); //8Frame情况下45ms的曝光时间一下都是400ms
        double baseExposureTime=45; //45ms的曝光时间
        double index=-1;
        int nRequiredSize = 0;
        RayCi_LiveMode_Camera_ExposureTime_getList(_nDocIdLive, NULL, &nRequiredSize);
        nRequiredSize=nRequiredSize+3;
        double lastExposureTime = 0.0;
        double lastGain = 0;
        double totaltime =0;
        QElapsedTimer timer;
        RayCi_LiveMode_Camera_ExposureTime_getExposureTime(_nDocIdLive, &lastExposureTime);
        RayCi_LiveMode_Camera_Gain_getGain(_nDocIdLive, &lastGain);
        timer.start();

        while(bRecording) {
            double nowExposureTime = 0.0;
            double nowGain = 0;
            double proportion = 0;
            int frame = 0;
            RayCi_LiveMode_Camera_ExposureTime_getExposureTime(_nDocIdLive, &nowExposureTime);
            if (isAllExposure) {

                RayCi_LiveMode_Camera_Gain_getGain(_nDocIdLive, &nowGain);

                if ( (std::abs(nowExposureTime - lastExposureTime) > std::numeric_limits<double>::epsilon())
                  || (nowGain != lastGain) )
                {
                    timer.restart();
                    lastExposureTime = nowExposureTime;
                    lastGain = nowGain;
                    index++;
                }
                if (nowExposureTime <=baseExposureTime) {
                    nowExposureTime = baseExposureTime;
                }
                totaltime = baseFrameTime * (nowExposureTime / baseExposureTime);
                proportion = index/nRequiredSize*100;

                frame =(timer.elapsed() / totaltime)* nowFreme;
                double frameRatio = static_cast<double>(frame) / nowFreme;
                proportion += frameRatio;
                if (proportion>((index+1)/nRequiredSize*100)) {
                    proportion = (index+1)/nRequiredSize*100;
                }
            }
            else {
                baseFrameTime=350*(nowFreme/8);
                baseExposureTime=30;
                if (nowExposureTime <=baseExposureTime) {
                    nowExposureTime = baseExposureTime;
                }
                totaltime = baseFrameTime*(nowExposureTime/baseExposureTime);
                frame = (timer.elapsed() / baseFrameTime) * nowFreme;
                proportion = (static_cast<double>(frame) / nowFreme) * 100;
            }
            if (proportion<0) {
                proportion=0;
            }
            if (proportion>100) {
                proportion=99;
            }
            // qDebug()<<"index"<<index<<"proportion"<<proportion<<"frame"<<frame<<"totaltime"<<
            //     totaltime<<"nowExposureTime"<<nowExposureTime<<"nowGain"<<nowGain;
            if (frame>=nowFreme) {
                emit BackGroundProgress(3,proportion,0,0);
            }
            else {
                emit  BackGroundProgress(3, proportion, frame, timer.elapsed());
            }
            RayCi_LiveMode_Background_Recording_isRecording(_nDocIdLive, &bRecording);
            QThread::msleep(50);
        }
        emit  BackGroundProgress(3, 100, nowFreme, totaltime);
        emit stopbackgroundWorkerThread();


        RayCi_LiveMode_Background_Recording_getRemarkA(_nDocIdLive, szRemark_buffer, &nSize);
        emit enableUI(true);
    }
    return {szRemark_buffer};
}

void LiveMode_Background::stopBackgroundMeasurement() const {

    RayCi_LiveMode_Background_Recording_stop(_nDocIdLive);
    emit stopbackgroundWorkerThread();

}




int LiveMode_Background::getFrameStepCount() {
    int stepCount = 0;
    RayCi_LiveMode_Background_Recording_Settings_getFrameStepCount(_nDocIdLive, &stepCount);
    return stepCount;
}
